package cn.com.sbell.vss.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.com.sbell.vss.csg.vap.bean.VideoSignal;
import cn.com.sbell.vss.csg.vsclient.util.CSGConfiguration;

public class VideoSignalDispatchGroup {
	private static final Log log = LogFactory
			.getLog(VideoSignalDispatchGroup.class);

	private final static Vector receivedVideoSignalList = new Vector();

	private volatile boolean running;

	private HttpClient httpClient;	

	private String cmsUrl;

	private static VideoSignalDispatchGroup signalDispatch;

	static{
		signalDispatch = new VideoSignalDispatchGroup();
		signalDispatch.init(CSGConfiguration.COMMON_VIDEO_STATE_DISPATCH_THREAD_NUM);
	}

	private VideoSignalDispatchGroup() {

	}

	public static VideoSignalDispatchGroup getSignalDispatchGroup() {
		return signalDispatch;
	}

	public class reportVideoSignalThread extends Thread {
		public void run() {
			log.info("Reporter VideoSignal Thread " + this + " started.");
			while (running) {
				try {
					VideoSignal videoSignal = (VideoSignal) receivedVideoSignalList.remove(0);
					if (log.isDebugEnabled()) {
						log.debug("Got an VideoSignal  ["
								+ videoSignal.getDeviceId()
								+ "] from TO-SEND queue");
					}
					if (reportVideoSignal(videoSignal)) {
						log.info("videoSignal SendOut: [DeviceId:"
								+ videoSignal.getDeviceId() + "]");
					}
				} catch (ArrayIndexOutOfBoundsException ex) {
					log.debug("debug by morris, ArrayIndexOutOfBoundsException receivedVideoSignalList.wait()...");
					try {
						synchronized (receivedVideoSignalList) {
							receivedVideoSignalList.wait();
						}
					} catch (InterruptedException e) {
						ex.printStackTrace();
					}
				} catch (Throwable ex) {
					log.warn("error", ex);
				}

			}
			log.debug("report videoSignal Thread " + this + " exited.");
		}

	}

	public void init(int reportThreadNumber) {
		running = true;
		log.debug("start init thread for videoSignalDispatch");
		log.debug("reportThreadNumber ="+reportThreadNumber);
		Thread[] thread = new reportVideoSignalThread[reportThreadNumber];
		for (int i = 0; i < thread.length; i++) {
			thread[i] = new reportVideoSignalThread();
			thread[i].setDaemon(true);
			thread[i].setPriority(Thread.MIN_PRIORITY);
			thread[i].start();
			log.debug("thread start "+thread[i].toString());
		}
	}

	public void destroy() {
		log.warn("Request to stop VideoSignalDispatch ...");
		running = false;
		synchronized (receivedVideoSignalList) {
			receivedVideoSignalList.notifyAll();
		}
	}

	private boolean reportVideoSignal(VideoSignal videoSignal) {
		boolean result = true;

		PostMethod method = new PostMethod(cmsUrl + "/ReportVideoState");

		// 如果参数为null，则不传给ems．
		addParametersToRequest(method, videoSignal);

		log.info("Send viodeSignal to " + cmsUrl + "/ReportVideoState");

		try {
			httpClient.executeMethod(method);
			method.getResponseBodyAsString();
		} catch (IOException e) {
			result = false;
			log.warn("Alarm Send-Failed:" + e);
		} finally {
			method.releaseConnection();
		}
		return result;
	}

	private void addParametersToRequest(PostMethod method,
			VideoSignal videoSignal) {
		ArrayList validParameterList = new ArrayList();

		if (null != videoSignal.getDeviceId()) {
			validParameterList.add(new NameValuePair("vsDeviceId", videoSignal
					.getDeviceId()));
		}
		if (null != videoSignal.getVideoState()
				&& videoSignal.getVideoState().length > 0) {
			for (int i = 0; i < videoSignal.getVideoState().length; i++) {
				String par = videoSignal.getVideoState()[i].getVideoId() + ","
						+ videoSignal.getVideoState()[i].getVideoState();
				log.debug("video states value is " + par);
				validParameterList.add(new NameValuePair("videoState", par));
			}

		}
		validParameterList.add(new NameValuePair("timestamp", videoSignal
				.getTimestamp()));
		NameValuePair[] parameters = (NameValuePair[]) validParameterList
				.toArray(new NameValuePair[0]);
		method.addParameters(parameters);
	}

	public void addVideoSignal(VideoSignal videoSignal) {
		receivedVideoSignalList.add(videoSignal);
		synchronized (receivedVideoSignalList) {
			receivedVideoSignalList.notifyAll();
		}
		log.debug("Added an Video Signal to RECEIVED queue");
	}

	// private String parseVideoStates(VideoState[] states){
	// StringBuffer buffer=new StringBuffer();
	// for (int i = 0; i < states.length; i++) {
	// if(i==states.length-1){
	// buffer.append(states[i].getVideoId()+","+states[i].getVideoState());
	// }else{
	// buffer.append(states[i].getVideoId()+","+states[i].getVideoState()+"&");
	// }
	// }
	// return buffer.toString();
	// }

	public String getCmsUrl() {
		return cmsUrl;
	}

	public void setCmsUrl(String cmsurl) {
		this.cmsUrl = cmsurl;
	}

	public HttpClient getHttpClient() {
		return httpClient;
	}

	public void setHttpClient(HttpClient httpClient) {
		this.httpClient = httpClient;
	}

	

}
